package Wuzi;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;

import static Wuzi.MusicPlay.play_Hit;


public class WPanel extends JPanel {
    private int x;
    private int y;
    private int ex;//待发送的坐标
    private int ey;
    private int currentPlayer = 1;
    private boolean showOrder;//是否显示顺序
    //private boolean playmusic=true;//是否显示顺序
    private boolean mode;//模式，true为人人，false为人机
    private boolean intel;//智能，true为估值函数，false为搜索树
    int depth;//搜索深度
    private int nodeCount;//每层节点
    private boolean first;//先手，true为人类，false为机器
    private boolean isGameOver;//true为游戏结束
    private int count = 1;//已经下棋的数目
    private JTextArea jt;
    private Chess chessBeansForTree;//搜索树返回结果
    private boolean newgame = false;
    boolean help= false;//是否请求帮助
    private int type=0;//棋型
    boolean playaudio= false;

    Chess[][] chess = new Chess[Wfinal.LINE_NUMBER][Wfinal.LINE_NUMBER];
   // Chess[][] chesstype1 = new Chess[Wfinal.LINE_NUMBER][Wfinal.LINE_NUMBER];
    public WPanel() {

        setPreferredSize(new Dimension(Wfinal.PANEL_WIDTH, Wfinal.PANEL_HEIGHT));
        setBackground(Color.orange);

        //棋盘绑定鼠标移动事件
        addMouseMotionListener(mouseMotionListener);
        addMouseListener(mouseListener);
        for (int i = 0; i < chess.length; i++) {
            for (int j = 0; j < chess[i].length; j++) {
                //测试通过黑白黑白顺序设置棋子
                chess[i][j] = new Chess(i, j, 0, 0);
                //currentplayer=3-currentplayer;
            }
        }

    }

    private MouseMotionListener mouseMotionListener = new MouseMotionListener() {


        @Override
        public void mouseMoved(MouseEvent e) {
            // TODO Auto-generated method stub
            //鼠标移动。获取坐标
            int x_temp = e.getX();
            int y_temp = e.getY();

            //判断是否越界
            if (x_temp > 0 && x_temp < Wfinal.LINE_NUMBER * Wfinal.LINE_SIZE && y_temp > 0 &&
                    y_temp < Wfinal.LINE_NUMBER * Wfinal.LINE_SIZE) {
                x = (x_temp - Wfinal.OFFSET / 2) / Wfinal.LINE_SIZE;
                y = (y_temp - Wfinal.OFFSET / 2) / Wfinal.LINE_SIZE;

                repaint();//重绘
            }

        }

        @Override
        public void mouseDragged(MouseEvent e) {
            // TODO Auto-generated method stub

        }
    };

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;//获取2d画笔
        g2d.setStroke(new BasicStroke(2)); // 加粗线
        drawLine(g2d);
        drawStar(g2d);
        drawTips(g2d);
        drawNumber(g2d);
        drawChess(g2d);
        drawOderNumber(g2d);
        doHelp(g2d);
    }

    //绘制下棋顺序
    private void drawOderNumber(Graphics2D g2d) {
        if (showOrder&&type==0) {
            g2d.setColor(Color.red);
            for (int i = 0; i < chess.length; i++) {
                for (int j = 0; j < chess[i].length; j++) {
                    Chess bean = chess[i][j];
                    if (bean.getPlayer() != Wfinal.WU) {
                        int num = bean.getOrder();
                        FontMetrics fontMetrics = g2d.getFontMetrics();
                        int width = fontMetrics.stringWidth(num + "");
                        int height = fontMetrics.getHeight();
                        //坐标
                        int x_tmp = Wfinal.OFFSET + bean.getX() * Wfinal.LINE_SIZE;
                        int y_tmp = Wfinal.OFFSET + bean.getY() * Wfinal.LINE_SIZE;
                        g2d.drawString(num + "", x_tmp - width / 4, y_tmp + height / 3);
                    }
                }
            }
        }
        if (!showOrder) {//最后一个棋子画标记点
            Chess bean = getLastBean();
            if (bean != null) {
                g2d.setColor(Color.red);
                int width = Wfinal.LINE_SIZE / 5;

                int x_tmp = Wfinal.OFFSET + bean.getX() * Wfinal.LINE_SIZE;
                int y_tmp = Wfinal.OFFSET + bean.getY() * Wfinal.LINE_SIZE;
                g2d.fillOval(x_tmp - width / 2, y_tmp - width / 2, width, width);
            }
        }

    }

    //绘制棋子
    private void drawChess(Graphics2D g2d) {
        for (int i = 0; i < chess.length; i++) {
            for (int j = 0; j < chess[i].length; j++) {
                Chess bean = chess[i][j];
                if (bean.getPlayer() != 0) {
                    if (bean.getPlayer() == Wfinal.BLACK) {
                        g2d.setColor(Color.black);//黑子
                    } else if (bean.getPlayer() == Wfinal.WHITE) {
                        g2d.setColor(Color.white);//白子
                    }

                    //计算坐标
                    int x_tmp = Wfinal.OFFSET + bean.getX() * Wfinal.LINE_SIZE;
                    int y_tmp = Wfinal.OFFSET + bean.getY() * Wfinal.LINE_SIZE;

                    int width = Wfinal.LINE_SIZE / 5 * 3;
                    g2d.fillOval(x_tmp - width / 2, y_tmp - width / 2, width, width);
                }
            }
        }
    }

    //棋盘数字
    private void drawNumber(Graphics2D g2d) {
        // TODO Auto-generated method stub
        g2d.setColor(Color.black);
        FontMetrics fonMetrics = g2d.getFontMetrics();
        //int height= fonMetrics.getHeight();
        //int height2= fonMetrics.getAscent();
        //左侧数字
        for (int i = 0; i < Wfinal.LINE_NUMBER; i++) {
            g2d.drawString((Wfinal.LINE_NUMBER - i) + "", Wfinal.OFFSET / 3, Wfinal.LINE_SIZE * (i + 1));
        }
        //底部字母
        for (int i = 0; i < Wfinal.LINE_NUMBER; i++) {
            String str = (char) (65 + i) + "";
            int width = fonMetrics.stringWidth(str);
            g2d.drawString(str, Wfinal.OFFSET + i * Wfinal.LINE_SIZE - width / 2,
                    Wfinal.OFFSET + Wfinal.LINE_NUMBER * Wfinal.LINE_SIZE);
        }


    }

    //画提示框
    private void drawTips(Graphics2D g2d) {
        // TODO Auto-generated method stub
        //计算交叉点的坐标
        g2d.setColor(Color.red);
        int x_temp = Wfinal.OFFSET + x * Wfinal.LINE_SIZE;
        int y_temp = Wfinal.OFFSET + y * Wfinal.LINE_SIZE;

        int half = Wfinal.LINE_SIZE / 2;
        int quarter = Wfinal.LINE_SIZE / 4;

        //左上角
        g2d.drawLine(x_temp - half, y_temp - half, x_temp - half + quarter, y_temp - half);
        g2d.drawLine(x_temp - half, y_temp - half, x_temp - half, y_temp - half + quarter);
        //左下角
        g2d.drawLine(x_temp - half, y_temp + half, x_temp - half + quarter, y_temp + half);
        g2d.drawLine(x_temp - half, y_temp + half, x_temp - half, y_temp + half - quarter);
        //右上角
        g2d.drawLine(x_temp + half, y_temp - half, x_temp + half - quarter, y_temp - half);
        g2d.drawLine(x_temp + half, y_temp - half, x_temp + half, y_temp - half + quarter);
        //右下角
        g2d.drawLine(x_temp + half, y_temp + half, x_temp + half - quarter, y_temp + half);
        g2d.drawLine(x_temp + half, y_temp + half, x_temp + half, y_temp + half - quarter);

    }

    //画天元
    private void drawStar(Graphics2D g2d) {
        // TODO Auto-generated method stub
        int half = Wfinal.LINE_NUMBER / 2;
        int quarter = Wfinal.LINE_NUMBER / 4;
        //天元
        g2d.fillOval(Wfinal.OFFSET + half * Wfinal.LINE_SIZE - Wfinal.STARE / 2,
                Wfinal.OFFSET + half * Wfinal.LINE_SIZE - Wfinal.STARE / 2, Wfinal.STARE, Wfinal.STARE);
        //左上角
        g2d.fillOval(Wfinal.OFFSET + quarter * Wfinal.LINE_SIZE - Wfinal.STARE / 2,
                Wfinal.OFFSET + quarter * Wfinal.LINE_SIZE - Wfinal.STARE / 2, Wfinal.STARE, Wfinal.STARE);
        //左下角
        g2d.fillOval(Wfinal.OFFSET + quarter * Wfinal.LINE_SIZE - Wfinal.STARE / 2, Wfinal.OFFSET + (Wfinal.LINE_NUMBER - quarter - 1) * Wfinal.LINE_SIZE - Wfinal.STARE / 2,
                Wfinal.STARE, Wfinal.STARE);
        //右上角
        g2d.fillOval(Wfinal.OFFSET + (Wfinal.LINE_NUMBER - quarter - 1) * Wfinal.LINE_SIZE - Wfinal.STARE / 2,
                Wfinal.OFFSET + quarter * Wfinal.LINE_SIZE - Wfinal.STARE / 2, Wfinal.STARE, Wfinal.STARE);
        //右下角
        g2d.fillOval(Wfinal.OFFSET + (Wfinal.LINE_NUMBER - quarter - 1) * Wfinal.LINE_SIZE - Wfinal.STARE / 2,
                Wfinal.OFFSET + (Wfinal.LINE_NUMBER - quarter - 1) * Wfinal.LINE_SIZE - Wfinal.STARE / 2, Wfinal.STARE, Wfinal.STARE);
    }

    //画线函数
    private void drawLine(Graphics2D g2d) {
        // TODO Auto-generated method stub
        //横线
        for (int i = 0; i < Wfinal.LINE_NUMBER; i++) {
            g2d.drawLine(Wfinal.OFFSET, Wfinal.OFFSET + i * Wfinal.LINE_SIZE,
                    Wfinal.OFFSET + Wfinal.LINE_SIZE * (Wfinal.LINE_NUMBER - 1), Wfinal.OFFSET + i * Wfinal.LINE_SIZE);
        }
        //竖线
        for (int i = 0; i < Wfinal.LINE_NUMBER; i++) {
            g2d.drawLine(Wfinal.OFFSET + i * Wfinal.LINE_SIZE, Wfinal.OFFSET,
                    Wfinal.OFFSET + i * Wfinal.LINE_SIZE, Wfinal.OFFSET + Wfinal.LINE_SIZE * (Wfinal.LINE_NUMBER - 1));
        }

    }

    //获取最后一颗棋子
    private Chess getLastBean() {
        Chess bean = null;
        for (int i = 0; i < chess.length; i++) {
            for (int j = 0; j < chess[i].length; j++) {
                Chess tmp = chess[i][j];
                if (tmp.getPlayer() != Wfinal.WU) {
                    if (bean == null) {
                        bean = tmp;
                    } else {
                        if (tmp.getOrder() > bean.getOrder()) {
                            bean = tmp;
                        }
                    }
                }
            }
        }
        return bean;
    }

    //显示顺序
    public void showOder(boolean showOder) {
        this.showOrder = showOder;
        repaint();//重绘
    }


    //帮助按钮,绘制提示框
    public void doHelp(Graphics2D g2d){
        boolean right;
        if(this.mode){
            right=true;
        }else{
            right=(this.first&& currentPlayer == 1)||(!this.first&&currentPlayer==2);
        }
        if(!isGameOver&&right&&newgame&&this.help) {
            List<Chess> orderList = getSortList(currentPlayer, chess);
            Chess bean = orderList.get(0);
            x = bean.getX();
            y = bean.getY();

            g2d.setColor(Color.blue);
            int x_temp = Wfinal.OFFSET + x * Wfinal.LINE_SIZE;
            int y_temp = Wfinal.OFFSET + y * Wfinal.LINE_SIZE;

            int half = Wfinal.LINE_SIZE / 2;
            int quarter = Wfinal.LINE_SIZE / 4;

            //左上角
            g2d.drawLine(x_temp - half, y_temp - half, x_temp - half + quarter, y_temp - half);
            g2d.drawLine(x_temp - half, y_temp - half, x_temp - half, y_temp - half + quarter);
            //左下角
            g2d.drawLine(x_temp - half, y_temp + half, x_temp - half + quarter, y_temp + half);
            g2d.drawLine(x_temp - half, y_temp + half, x_temp - half, y_temp + half - quarter);
            //右上角
            g2d.drawLine(x_temp + half, y_temp - half, x_temp + half - quarter, y_temp - half);
            g2d.drawLine(x_temp + half, y_temp - half, x_temp + half, y_temp - half + quarter);
            //右下角
            g2d.drawLine(x_temp + half, y_temp + half, x_temp + half - quarter, y_temp + half);
            g2d.drawLine(x_temp + half, y_temp + half, x_temp + half, y_temp + half - quarter);

        }
    }

    //是否点击帮助
    public void isHelp(boolean help){
        this.help=help;
        repaint();
    }

    //是否播放音效
    public void playAudio(boolean playaudio) {
        this.playaudio = playaudio;
    }

    //读取棋盘
    public void readtype(int ty,Chess[][] chess){
        try {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("type"+ty+".txt"));
            for (int i = 0; i < chess.length; i++) {
                for (int j = 0; j < chess[i].length; j++) {
                    chess[i][j] = (Chess) ois.readObject();
                }
            }
        } catch(Exception e) {
            e.printStackTrace();
        }

    }

    //新游戏
    public void newGame(boolean mode, boolean intel, int depth, int nodeCount, boolean first, boolean showOrder, JTextArea jt, int type) {
        this.newgame = true;
        this.mode = mode;
        this.intel = intel;
        this.depth = depth;
        this.nodeCount = nodeCount;
        this.first = first;
        this.showOrder = showOrder;
        this.jt = jt;
        this.jt.setText("");
        this.type=type;
        //开局默认黑子
        currentPlayer = Wfinal.BLACK;
        //初始化
        for (int i = 0; i < chess.length; i++) {
            for (int j = 0; j < chess[i].length; j++) {
                chess[i][j] = new Chess(i, j, 0, 0);
            }
        }
        isGameOver = false;
        count = 0;
        if(this.type!=0)
        {
            readtype(this.type,chess);
            count=43;
        }

        //弹出提醒
        JOptionPane.showMessageDialog(WPanel.this, "新游戏开始！");
        //人机，机器先手
        if(type!=0)
        {
            JOptionPane.showMessageDialog(WPanel.this, "该棋局下不支持电脑先手");
        }
        if (!mode && !first&&type==0) {
            int centre = Wfinal.LINE_NUMBER / 2;
            chess[centre][centre].setPlayer(currentPlayer);
            chess[centre][centre].setOrder(count);
            count++;
            currentPlayer = 3 - currentPlayer;
        }
        repaint();//重绘

    }

    MouseListener mouseListener = new MouseListener() {

        @Override
        public void mouseReleased(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mousePressed(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseExited(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseEntered(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseClicked(MouseEvent e) {
            if (isGameOver) {
                JOptionPane.showMessageDialog(WPanel.this, "游戏已经结束！");
                return;
            }
            if (!newgame) {
                JOptionPane.showMessageDialog(WPanel.this, "游戏未开始！");
                return;
            }
            //鼠标移动。获取坐标
            int x_temp = e.getX();
            int y_temp = e.getY();

            //判断是否越界
            if (x_temp > 0 && x_temp < Wfinal.LINE_NUMBER * Wfinal.LINE_SIZE && y_temp > 0 &&
                    y_temp < Wfinal.LINE_NUMBER * Wfinal.LINE_SIZE) {
                x = (x_temp - Wfinal.OFFSET / 2) / Wfinal.LINE_SIZE;
                y = (y_temp - Wfinal.OFFSET / 2) / Wfinal.LINE_SIZE;
            }


            if (e.getButton() == MouseEvent.BUTTON1) {
                if (mode) {
                    //人人对战,落子
                    if (chess[x][y].getPlayer() == Wfinal.WU) {
                        chess[x][y] = new Chess(x, y, currentPlayer, count);
                        count++;
                        currentPlayer = 3 - currentPlayer;
                        if(playaudio){
                            play_Hit();
                        }
                        help=false;
                    }
                    repaint();
                    checkWin(x, y, chess[x][y].getPlayer());

                } else {

                    if (chess[x][y].getPlayer() == Wfinal.WU) {
                        chess[x][y] = new Chess(x, y, currentPlayer, count);
                        count++;
                        help=false;
                        if(playaudio){
                            play_Hit();
                        }
                        repaint();
                        boolean win = checkWin(x, y, chess[x][y].getPlayer());
                        currentPlayer = 3 - currentPlayer;
                        if (intel) {
                            //机器下棋,估值函数
                            if (!win) {
                                List<Chess> orderList = getSortList(currentPlayer, chess);
                                Chess bean = orderList.get(0);
                                x = bean.getX();
                                y = bean.getY();
                                bean.setPlayer(currentPlayer);
                                bean.setOrder(count++);
                                chess[x][y] = bean;
                                currentPlayer = 3 - currentPlayer;
                                if(playaudio){
                                    play_Hit();
                                }
                                help=false;
                                repaint();
                                checkWin(x, y, chess[x][y].getPlayer());

                            }

                        } else {
                            if (!win) {
                                // 电脑下棋，找到估值最大的
                                Chess bean;
                                getValueByTrees2(0, Wfinal.BLACK, chess, -Integer.MAX_VALUE,
                                        Integer.MAX_VALUE);
                                bean = chessBeansForTree;
                                x = bean.getX();
                                y = bean.getY();
                                bean.setPlayer(currentPlayer);
                                bean.setOrder(count++);
                                chess[x][y] = bean;
                                currentPlayer = 3 - currentPlayer;
                                if(playaudio){
                                    play_Hit();
                                }
                                help=false;
                                repaint();
                                checkWin(x, y, chess[x][y].getPlayer());

                            }
                        }

                    }

                }
            } else if (e.getButton() == MouseEvent.BUTTON3) {
                // 右键
                if (x >= 0 && x < Wfinal.LINE_NUMBER && y >= 0 && y < Wfinal.LINE_NUMBER) { // 判断是否在棋盘内
                    Chess[][] temBeans = WPanel.this.clone(chess);
                    int offense = getValue(x, y, currentPlayer, temBeans);
                    // 计算该点对对手的价值
                    int defentse = getValue(x, y, 3 - currentPlayer, temBeans);

                    temBeans[x][y].getBuffer().append("点(" + x + "," + y + ")的" + "攻击:" + offense + " "
                            + "防御:" + defentse + " " + "总和:" + (defentse + offense) + "\n\n");
                    jt.append(temBeans[x][y].getBuffer().toString());
                    // }

                }
            }
        repaint();
    }

};

    //克隆函数
    private Chess[][] clone(Chess[][] chessBeans)
    {
        Chess[][] tempBeans = new Chess[Wfinal.LINE_NUMBER][Wfinal.LINE_NUMBER];
        for(int i=0;i<chessBeans.length;i++)
        {
            for(int j=0;j<chessBeans[i].length;j++)
            {
                tempBeans[i][j] = new Chess(chessBeans[i][j].getX(),chessBeans[i][j].getY(),chessBeans[i][j].getPlayer(),
                        chessBeans[i][j].getOrder());
            }
        }
        return tempBeans;
    }


    //极大极小值搜索,未剪枝搜索树
    protected Chess getValueByTrees(int d, int player, Chess[][] chessBeans) {
        Chess[][] tempBeans = clone(chessBeans);
        List<Chess> orderList = getSortList(player, tempBeans);
        if (d == depth) {
            return orderList.get(0); // 达到搜索指定深度，结束。返回当前步骤中。获取到的估值最高的点。
        }
        for (int i = 0; i < orderList.size(); i++) {
            // 遍历当前棋盘上所有空余的位置（遍历getSortList）
            System.out.println("i" + i);
            Chess bean = orderList.get(i);
            if (bean.getSum() > Level.ALIVE_4.score) {
                return bean;
            } else {
                // 这个步骤是模拟下棋。不能再真正的棋盘上进行落子
                tempBeans[bean.getX()][bean.getY()].setPlayer(player);
                return getValueByTrees(d + 1, 3 - player, tempBeans);
            }
        }
        return null;
    }


    //剪枝搜素树
    protected int getValueByTrees2(int d, int player, Chess[][] chessBeans2, int alpha, int beta) {
        Chess[][] temBeans = clone(chessBeans2);
        List<Chess> orderList = getSortList(player, temBeans);
        if (d == depth) {
            // 达到搜索指定深度，结束。返回当前步骤中。获取到的估值最高的点。
            return orderList.get(0).getSum();
        }
        // 遍历当前棋盘上所有空余的位置（遍历getSortList）
        for (int i = 0; i < nodeCount; i++) {
            Chess bean = orderList.get(0);
            int score;
            if (bean.getSum() > Level.ALIVE_4.score) {
                // 找到目标
                score = bean.getSum();
            } else {
                // 这个步骤是模拟下棋。不能再真正的棋盘上进行落子
                temBeans[bean.getX()][bean.getY()].setPlayer(player);
                // temBeans[bean.getX()][bean.getY()] = bean;
                score = getValueByTrees2(d + 1, 3 - player, temBeans, alpha, beta);
            }
            if (d % 2 == 0) {
                // 自己，找最大值
                if (score > alpha) {
                    alpha = score;
                    if (d == 0) {
                        // 结果
                        chessBeansForTree = bean;
                    }
                }
                if (alpha >= beta) {
                    // 剪枝
                    score = alpha;
                    return score;
                }
            } else {
                if (score < beta) {
                    beta = score;
                }
                if (alpha >= beta) {
                    // 剪枝
                    score = beta;
                    return score;
                }
            }
        }
        return d % 2 == 0 ? alpha : beta;
    }
    
    //得到排列好的棋子
    private List<Chess> getSortList(int currentplayer, Chess[][] tempBeans) {
        List<Chess>list=new ArrayList<Chess>();
        for(Chess[]chessBean2:tempBeans) {
            for(Chess chessBean:chessBean2) {
                if(chessBean.getPlayer()==Wfinal.WU) {//空棋
                    int offense=getValue(chessBean.getX(),chessBean.getY(),currentplayer,tempBeans);//获取分值
                    int defense=getValue(chessBean.getX(),chessBean.getY(),3-currentplayer,tempBeans);

                    chessBean.setOffense(offense);//攻击分值
                    chessBean.setDefense(defense);//防守分值
                    chessBean.setSum(offense+defense);
                    list.add(chessBean);
                }
            }
        }
        //总分值排序
        Collections.sort(list);
        return list;

    }



    //获取分数
    private int getValue(int x2, int y2, int player, Chess[][] tempBeans) {
        Level level1 = getLevel(x2, y2, Direction.HENG, player, tempBeans);
        Level level2 = getLevel(x2, y2, Direction.SHU, player, tempBeans);
        Level level3 = getLevel(x2, y2, Direction.PIE, player, tempBeans);
        Level level4 = getLevel(x2, y2, Direction.NA, player, tempBeans);
        return levelScore(level1, level2, level3, level4) + position[x2][y2];
    }


    //字符串匹配棋型，得到分值
    private int levelScore(Level level1, Level level2, Level level3, Level level4) {
        int[] levelCount = new int[Level.values().length];
        for (int i = 0; i < Level.values().length; i++) {
            levelCount[i] = 0;
        }
        // 统计某一个棋型出现的次数
        levelCount[level1.index]++;
        levelCount[level2.index]++;
        levelCount[level3.index]++;
        levelCount[level4.index]++;

        int score = 0;
        if (levelCount[Level.GO_4.index] >= 2
                || levelCount[Level.GO_4.index] >= 1 && levelCount[Level.ALIVE_3.index] >= 1)// 双活4，冲4活三
            score = 10000;
        else if (levelCount[Level.ALIVE_3.index] >= 2)// 双活3
            score = 5000;
        else if (levelCount[Level.SLEEP_3.index] >= 1 && levelCount[Level.ALIVE_3.index] >= 1)// 活3眠3
            score = 1000;
        else if (levelCount[Level.ALIVE_2.index] >= 2)// 双活2
            score = 100;
        else if (levelCount[Level.SLEEP_2.index] >= 1 && levelCount[Level.ALIVE_2.index] >= 1)// 活2眠2
            score = 10;
        score = Math.max(score, Math.max(Math.max(level1.score, level2.score), Math.max(level3.score, level4.score)));
        return score;
    }

    //判断棋型
    private Level getLevel(int x2, int y2, Direction direction, int player, Chess[][] tempBeans) {
        String leftString = "";
        String rightString = "";

        String str;

        if (direction == Direction.HENG) {
            leftString = getStringSeq(x2, y2, -1, 0, player, tempBeans);
            rightString = getStringSeq(x2, y2, 1, 0, player, tempBeans);
        } else if (direction == Direction.SHU) {
            leftString = getStringSeq(x2, y2, 0, -1, player, tempBeans);
            rightString = getStringSeq(x2, y2, 0, 1, player, tempBeans);
        } else if (direction == Direction.PIE) {
            leftString = getStringSeq(x2, y2, -1, 1, player, tempBeans);
            rightString = getStringSeq(x2, y2, 1, -1, player, tempBeans);
        } else if (direction == Direction.NA) {
            leftString = getStringSeq(x2, y2, -1, -1, player, tempBeans);
            rightString = getStringSeq(x2, y2, 1, 1, player, tempBeans);
        }

        str = leftString + player + rightString;
        tempBeans[x2][y2].getBuffer().append("(" + (x2 + 1) + "," + (y2 - 1) + ")" + direction + "\t" + str + "\t");

        // 获取棋型的倒置字符串
        String s = new StringBuilder(str).reverse().toString();
        // 根据str和rstr去Level里进行棋型匹配
        for (Level level : Level.values()) {
            Pattern pat = Pattern.compile(level.regex[player - 1]);
            Matcher mat = pat.matcher(str); // 正
            // 如果是true则匹配成功
            boolean r1 = mat.find();
            mat = pat.matcher(s); // 反
            // 如果是true则匹配成功
            boolean r2 = mat.find();
            if (r1 || r2) {
                tempBeans[x2][y2].getBuffer().append(level.name + "\n");
                if (direction == Direction.NA) {
                    tempBeans[x2][y2].getBuffer().append("\n");
                }
                return level;
            }
        }
        return Level.NULL;
    }

    //计算棋形4个方向的字符串
    private String getStringSeq(int x2, int y2, int i, int j, int player, Chess[][] tempBeans) {
        String sum = "";
        boolean isRight = false;
        if (i < 0 || (i == 0 && j < 0)) {
            isRight = true;
        }
        for (int k = 0; k < 5; k++) {
            x2 += i;
            y2 += j;
            if (x2 > 0 && x2 < Wfinal.LINE_NUMBER && y2 > 0 && y2 < Wfinal.LINE_NUMBER) {
                if (isRight) {
                    sum = tempBeans[x2][y2].getPlayer() + sum;
                } else {
                    sum = sum + tempBeans[x2][y2].getPlayer();
                }
            }
        }
        return sum;
    }

    //判断胜负
    protected boolean checkWin(int x2, int y2, int player) {
                boolean win = false;
                if (check(x2, y2, 1, 0, player) + check(x2, y2, -1, 0, player) >= 4) {// 检查横是否有五子相连
                    win = true;
                } else if (check(x2, y2, 0, 1, player) + check(x2, y2, 0, -1, player) >= 4) {// 检查竖是否有五子相连
                    win = true;
                } else if (check(x2, y2, 1, 1, player) + check(x2, y2, -1, -1, player) >= 4) {// 检查横是否有五子相连
                    win = true;
                } else if (check(x2, y2, -1, 1, player) + check(x2, y2, 1, -1, player) >= 4) {// 检查横是否有五子相连
                    win = true;
                }
                if (win) {
                    // if(player==1)
                    JOptionPane.showMessageDialog(WPanel.this, "游戏已经结束");
                    isGameOver = true;
                    return true;
                }
                return false;
            }

    //检查棋型
    private int check(int x2, int y2, int i, int j, int player) {
        // 向某个方向（i, j）检查4个棋子。
        int sum = 0;
        for (int k = 0; k < 4; k++) {
            x2 += i;
            y2 += j;
            if (x2 >= 0 && x2 < Wfinal.LINE_NUMBER && y2 >= 0 && y2 < Wfinal.LINE_NUMBER) {
                if (chess[x2][y2].getPlayer() == player) {
                    sum++;
                } else {
                    break;
                }
            }
        }
        return sum;
    }

    //悔棋
    public void huiQi() {
        if(isGameOver) {
            JOptionPane.showMessageDialog(WPanel.this, "请先开始游戏!");
            return;
        }else {
            if(mode) {//人人模式
                if(this.type==0&&count>1||this.type!=0&&count>43) {
                    Chess bean=getLastBean();
                    chess[bean.getX()][bean.getY()].setOrder(0);
                    chess[bean.getX()][bean.getY()].setPlayer(Wfinal.WU);
                    count--;
                    currentPlayer=3-currentPlayer;
                    repaint();
                }else {
                    JOptionPane.showMessageDialog(WPanel.this, "请先下棋!");
                    return;
                }
            }else {//人机模式
                if(this.type==0&&count>2||this.type!=0&&count>=45) {
                    for (int i = 0; i < 2; i++) {
                        Chess tempBean = getLastBean();
                        currentPlayer = tempBean.getPlayer();
                        chess[tempBean.getX()][tempBean.getY()].setPlayer(Wfinal.WU); //
                        chess[tempBean.getX()][tempBean.getY()].setOrder(0);
                        count--;
                        currentPlayer=this.first?1:2;
                    }
                    repaint();
                }else {
                    JOptionPane.showMessageDialog(WPanel.this, "请先下棋!");
                    return;
                }
            }

        }

    }

    // 棋型信息
    public static enum Level {
        CON_5("长连", 0, new String[] { "11111", "22222" }, 100000),
        ALIVE_4("活四", 1, new String[] { "011110", "022220" }, 10000),
        GO_4("冲四", 2, new String[] { "011112|0101110|0110110", "022221|0202220|0220220" }, 500),
        DEAD_4("死四", 3, new String[] { "211112", "122221" }, -5),
        ALIVE_3("活三", 4, new String[] { "01110|010110", "02220|020220" }, 200),
        SLEEP_3("眠三", 5,
                new String[] { "001112|010112|011012|10011|10101|2011102", "002221|020221|022021|20022|20202|1022201" },
                50),
        DEAD_3("死三", 6, new String[] { "21112", "12221" }, -5),
        ALIVE_2("活二", 7, new String[] { "00110|01010|010010", "00220|02020|020020" }, 5),
        SLEEP_2("眠二", 8,
                new String[] { "000112|001012|010012|10001|2010102|2011002",
                        "000221|002021|020021|20002|1020201|1022001" },
                3),
        DEAD_2("死二", 9, new String[] { "2112", "1221" }, -5), NULL("null", 10, new String[] { "", "" }, 0);
        private String name;
        private int index;
        private String[] regex;// 正则表达式
        int score;// 分值

        // 构造方法
        private Level(String name, int index, String[] regex, int score) {
            this.name = name;
            this.index = index;
            this.regex = regex;
            this.score = score;
        }

        // 覆盖方法
        @Override
        public String toString() {
            return this.name;
        }
    };

    // 方向
    private static enum Direction {
        HENG, SHU, PIE, NA
    };

    // 位置分
    private static int[][] position = {
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
            { 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0 },
            { 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0 },
            { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 3, 2, 1, 0 },
            { 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 4, 3, 2, 1, 0 },
            { 0, 1, 2, 3, 4, 5, 6, 6, 6, 5, 4, 3, 2, 1, 0 },
            { 0, 1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1, 0 },
            { 0, 1, 2, 3, 4, 5, 6, 6, 6, 5, 4, 3, 2, 1, 0 },
            { 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 4, 3, 2, 1, 0 },
            { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 3, 2, 1, 0 },
            { 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0 },
            { 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0 },
            { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };

    public void playchess(int x,int y){
        if (chess[x][y].getPlayer() == Wfinal.WU) {
            chess[x][y] = new Chess(x, y, currentPlayer, count);
            count++;
            currentPlayer = 3 - currentPlayer;
            if(playaudio){
                play_Hit();
            }
            help=false;
        }
        repaint();
        checkWin(x, y, chess[x][y].getPlayer());
    }

    public String sendxy(){
        return (x+":"+y);
    }
}

